//
//  AFGetData.m
//  MVideo
//
//  Created by Lin Eidan on 14-3-21.
//  Copyright (c) 2014年 taomee. All rights reserved.
//

#import "DownloadGetData.h"
#import "LocalFileManage.h"
#import "config.h"
#import "Header.h"
#import "VideoObj.h"

#define BackgroundSessionConfiguration      ([NSString stringWithFormat:@"com.haomee.%@",AppleAppID])

@interface DownloadGetData ()

@end

@implementation DownloadGetData

+ (DownloadGetData *)sharedInstance
{
    
    static DownloadGetData *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[DownloadGetData alloc] init];
    });
    return _sharedInstance;
}

-(id)init{
    self = [super init];
    if (self) {
        [self setUpMy];
    }
    return self;
}


-(void)setUpMy{
    
    NSURLSessionConfiguration *backConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:BackgroundSessionConfiguration];
    self.sessionBackManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:backConfig];
    self.sessionBackManager.responseSerializer =[AFHTTPResponseSerializer serializer];
    
    [self.sessionBackManager setDidFinishEventsForBackgroundURLSessionBlock:^(NSURLSession *session) {
//        if (kApp.backgroundSessionCompletionHandler && [DownloadVideoManager sharedInstance].downloadQueue.count == 0) {
//            void (^completionHandler)() = kApp.backgroundSessionCompletionHandler;
//            kApp.backgroundSessionCompletionHandler = nil;
//            completionHandler();
//            NSLog(@"All tasks are finished");
//        }
    }];
    
}

#pragma mark -IOS6 download
-(AFDownloadRequestOperation *)startDownload:(NSString *)url andFilePath:(NSString *)filePath andAllowResume:(BOOL)allowResume andProgress:(downloadProgessBlock)progessBlock andCompletion:(downloadCompletionBlock)block{
    
    NSURLRequestCachePolicy cachePolicy = NSURLRequestUseProtocolCachePolicy;
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url] cachePolicy:cachePolicy timeoutInterval:3600];
    
    AFDownloadRequestOperation *operation =[[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:filePath shouldResume:allowResume];
    
    [operation setProgressiveDownloadProgressBlock:^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
        float per= (float)totalBytesReadForFile/(float)(totalBytesExpectedToReadForFile);
        progessBlock(operation,per,totalBytesReadForFile,totalBytesExpectedToReadForFile);
    }];
    
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSDictionary *header = operation.response.allHeaderFields;
        long long contentLength = [self getContentLengthWithHeaderInfo:header];
        block(operation,contentLength,YES);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        block(operation,0,NO);
    }];
    
    [self.operationManager.operationQueue addOperation:operation];
    
    return operation;
}

#pragma mark -IOS7 Fore download
-(NSURLSessionDownloadTask *)startTaskDownload:(NSString *)url andFileFolderPath:(NSString *)fileFolderPath andFileName:(NSString *)fileName andAllowResume:(BOOL)allowResume andStartRightNow:(BOOL)rightRow andResumeData:(NSData *)resumeData andProgress:(downloadProgessTaskBlock)progessBlock andCompletion:(downloadCompletionTaskBlock)block{
    
    NSURLSessionDownloadTask *downTask = [self trueStartTaskDownloadWithSessionManager:self.sessionHttpManager andURL:url andFileFolderPath:fileFolderPath andFileName:fileName andAllowResume:allowResume andStartRightNow:rightRow andResumeData:resumeData andProgress:progessBlock andCompletion:block];
    
    return downTask;
}

#pragma mark -IOS7 Back getData
-(NSURLSessionDownloadTask *)startTaskBackgroundDataGet:(NSString *)url andFileFolderPath:(NSString *)fileFolderPath andFileName:(NSString *)fileName andResultIsJSON:(BOOL)iSJSON andTaskCompletion:(downloadCompletionGetDataTaskBlock)block{
    
    NSURLSessionDownloadTask *downTask = [self trueStartTaskDownloadWithSessionManager:self.sessionBackManager andURL:url andFileFolderPath:fileFolderPath andFileName:fileName andAllowResume:NO andStartRightNow:YES andResumeData:nil andProgress:^(NSURLSessionDownloadTask *task, float percent) {
    } andCompletion:^(NSURLResponse *response,long long contentLength, BOOL isSuccess) {
        if (isSuccess) {
            NSString *filePath = [NSString stringWithFormat:@"%@/%@",fileFolderPath,fileName];
            NSData *data = [NSData dataWithContentsOfMappedFile:filePath];
            if (iSJSON) {
                id responseJSON = [self convertDataToJsonFromData:data];
                block(response, responseJSON, isSuccess);
            }else{
                block(response, data, isSuccess);
            }
        }else{
            block(response,nil,isSuccess);
        }
        
    }];
    return downTask;
    
}

#pragma mark -IOS7 Back download
-(NSURLSessionDownloadTask *)startTaskBackgroundDownload:(NSString *)url andFileFolderPath:(NSString *)fileFolderPath andFileName:(NSString *)fileName andAllowResume:(BOOL)allowResume andStartRightNow:(BOOL)rightRow andResumeData:(NSData *)resumeData andProgress:(downloadProgessTaskBlock)progessBlock andCompletion:(downloadCompletionTaskBlock)block{
    
    NSURLSessionDownloadTask *downTask = [self trueStartTaskDownloadWithSessionManager:self.sessionBackManager andURL:url andFileFolderPath:fileFolderPath andFileName:fileName andAllowResume:allowResume andStartRightNow:rightRow andResumeData:resumeData andProgress:progessBlock andCompletion:block];
    
    return downTask;
}

#pragma mark -取消请求 和 处理不正常退出
-(void)removeAllDownloadRelatedRequest{
    
    [self removeAllGetAndPostRequest]; //ios6下即清除了get请求也清除了下载请求,ios7清除了所有前台请求，包括数据和下载
    
    if (isiOS7) {   //ios7清除了所有后台请求，包括数据和下载
        for (NSURLSessionTask *task in self.sessionBackManager.tasks) {
            [task cancel];
        }
    }
}

-(void)handleResumeDataWhenLastCrashWith:(id )delegate andTask:(NSURLSessionTask *)task andError:(NSError *)error{
    //这边delegate需为nil，才能表示是上次不正常退出，因为delegate还没有，如果没有加这个条件，每次点击暂停也会调用这个。
    if (error && delegate == nil) {
        for (VideoObj *obj in [[DownloadVideoManager sharedInstance] downloadQueue]) {
            if ([obj.episodeId isEqualToString:task.taskDescription]) {
                obj.downTaskResumeData =  [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData];
                break;
            }
        }
    }
}

//取消下载，要删除tmp文件
-(void)deleteTheTempFileWithResumeData:(NSData *)resumeData{
    NSString *string = [[NSString alloc] initWithData:resumeData encoding:NSUTF8StringEncoding];
    
    NSRange httpRange = [string rangeOfString:@"<key>NSURLSessionResumeInfoLocalPath</key>"];
    if (httpRange.location != NSNotFound) {
        NSString *lastString = [string substringFromIndex:(httpRange.location+httpRange.length)];
        NSRange startRange = [lastString rangeOfString:@"<string>"];
        NSRange endRange = [lastString rangeOfString:@"</string>"];
        
        if (endRange.location != NSNotFound && startRange.location != NSNotFound) {
            NSString *filePath = [lastString substringWithRange:NSMakeRange(startRange.location+8, endRange.location-startRange.location-8)];
            [LocalFileManage deleteFile:filePath];
        }
    }
}

#pragma mark -Public
-(NSURLSessionDownloadTask *)trueStartTaskDownloadWithSessionManager:(AFURLSessionManager *)sessionManager andURL:(NSString *)url andFileFolderPath:(NSString *)fileFolderPath andFileName:(NSString *)fileName andAllowResume:(BOOL)allowResume andStartRightNow:(BOOL)rightRow andResumeData:(NSData *)resumeData andProgress:(downloadProgessTaskBlock)progessBlock andCompletion:(downloadCompletionTaskBlock)block{
    
    NSURL *fileFolderURL = [NSURL fileURLWithPath:fileFolderPath];
    NSURL *filePathURL = [fileFolderURL URLByAppendingPathComponent:fileName];
    NSURLSessionDownloadTask *downTask;
    
    if (resumeData && allowResume) {
        resumeData = [self handleResumeData:resumeData withNewURL:url];
        
        downTask = [sessionManager downloadTaskWithResumeData:resumeData progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
            return filePathURL;
        } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
            if (error == nil) {
                NSDictionary *header = ((NSHTTPURLResponse *)response).allHeaderFields;
                long long contentLength = [self getContentLengthWithHeaderInfo:header];
                block(response,contentLength,YES);
            }else{
                block(response,0,NO);
            }
        }];
    }else{
    
        NSURL *URL = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        
        downTask = [sessionManager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
            return filePathURL;
        } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
            if (error == nil) {
                NSDictionary *header = ((NSHTTPURLResponse *)response).allHeaderFields;
                long long contentLength = [self getContentLengthWithHeaderInfo:header];
                block(response,contentLength,YES);
            }else{
                block(response,0,NO);
            }
        }];

        
        if (resumeData) {  //只要到这个里面了，请求就重新开始，之前有的也要删掉,特别是不支持断点续传，之前的tmp就要删掉。
            [self deleteTheTempFileWithResumeData:resumeData];
        }
        
    }
    
    if (downTask == nil) {  //因为有可能为nil，如果为nil，那么就是失败。
        block(nil,0,NO);
    }
    
    
    [sessionManager setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        float per= (float)totalBytesWritten/(float)(totalBytesExpectedToWrite);
        progessBlock(downloadTask,per);
    }];
   
    
    if (rightRow) {
        [downTask resume];
    }
    
    return downTask;
    
}

//获得大小
-(long long)getContentLengthWithHeaderInfo:(NSDictionary *)header{
    long long contentLength = 0;
    if ([header objectForKey:@"Content-Range"]) {
        NSString *contentRange = [header objectForKey:@"Content-Range"];
        NSRange range =  [contentRange rangeOfString:@"/" options:NSBackwardsSearch];
        if (range.location != NSNotFound) {
            NSString *length = [contentRange substringFromIndex:range.location+1];
            contentLength = [length longLongValue];
        }else{
            contentLength = [[header objectForKey:@"Content-Length"] longLongValue];
        }
        
    }else{
        contentLength = [[header objectForKey:@"Content-Length"] longLongValue];
    }
    return contentLength;
}

//因为地址可能失效，所以每次断点续传，把新地址传进去data里，利用新地址去请求。
-(NSData *)handleResumeData:(NSData *)resumeData withNewURL:(NSString *)url{
    NSMutableString *newUrl = [NSMutableString stringWithString:url];
    [newUrl replaceOccurrencesOfString:@"&" withString:@"&amp;" options:NSLiteralSearch range:NSMakeRange(0, url.length)];
    NSMutableString *string = [[NSMutableString alloc] initWithData:resumeData encoding:NSUTF8StringEncoding];
    
    NSRange httpRange = [string rangeOfString:@"<string>http:"];
    if (httpRange.location != NSNotFound) {
        NSRange endRange = [string rangeOfString:@"</string>"];
        if (endRange.location != NSNotFound) {
            [string replaceCharactersInRange:NSMakeRange(httpRange.location+8, endRange.location - httpRange.location -8) withString:newUrl];
        }
    }
    resumeData = [string dataUsingEncoding:NSUTF8StringEncoding];
    return resumeData;
}

//-(void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//    if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) {
//        // !!Note:-cancel method resumeData is empty!
//        if (error.userInfo && [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]) {
//            //            if (self.downloadInfoDictionary == nil) {
//            //                [self loadDownloadInfoDictionary];
//            //            }
//            NSLog(@"fdffffff");
//            // If you restart app,it will call this method with resumeData
//            //            KDownloadInfo *di = [self downloadInfoWithTaskIdentifier:task.taskIdentifier];
//            //            if (di) {
//            //                di.resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData];
//            //            }
//        }
//    }
//}



@end
